package com.base.netlib

import android.app.Application
import com.base.netlib.constant.NetWorkConstant
import com.base.netlib.constant.NetWorkConstant.DEFAULT_CONNECT_TIMEOUT
import com.base.netlib.constant.NetWorkConstant.DEFAULT_READ_TIMEOUT
import com.base.netlib.constant.NetWorkConstant.DEFAULT_WRITE_TIMEOUT
import com.base.netlib.interceptor.HeaderInterceptor
import com.base.netlib.interceptor.RetryInterceptor
import kotlinx.coroutines.flow.MutableSharedFlow
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import java.util.concurrent.TimeUnit


object NetLib {
    lateinit var application: Application
    val netErrorFlow = MutableSharedFlow<Throwable>()
    val mBuilder: HummerConfig by lazy {
        HummerConfig(mOkHttpBuilder)
    }
    val mOkHttpBuilder: OkHttpClient.Builder by lazy {
        OkHttpClient.Builder()
    }

    @JvmStatic
    fun config(context: Application): HummerConfig {
        application = context
        return mBuilder
    }
}

class HummerConfig(private val mOkHttpBuilder: OkHttpClient.Builder) {
    var baseUrl: String = ""

    private val mHeaderInterceptor: HeaderInterceptor by lazy {
        HeaderInterceptor()
    }

    init {
        setConnectTimeout(DEFAULT_CONNECT_TIMEOUT, TimeUnit.SECONDS).setReadTimeout(
                DEFAULT_READ_TIMEOUT,
                TimeUnit.SECONDS
            ).setWriteTimeout(DEFAULT_WRITE_TIMEOUT, TimeUnit.SECONDS)
            .addInterceptor(mHeaderInterceptor).addInterceptor(HttpLoggingInterceptor().apply {
                this.level = HttpLoggingInterceptor.Level.BODY
            })
    }

    /**
     * 添加拦截器
     */
    fun addInterceptor(interceptor: Interceptor): HummerConfig {
        mOkHttpBuilder.addInterceptor(interceptor)
        return this
    }

    /**
     * 连接超时时间
     * @param timeout 超时时间
     * @param unit 单位
     */
    fun setConnectTimeout(timeout: Long, unit: TimeUnit = TimeUnit.SECONDS): HummerConfig {
        mOkHttpBuilder.connectTimeout(timeout, unit)
        return this
    }

    /**
     * 读取超时时间
     * @param timeout 超时时间
     * @param unit 单位
     */
    fun setReadTimeout(timeout: Long, unit: TimeUnit = TimeUnit.SECONDS): HummerConfig {
        mOkHttpBuilder.readTimeout(timeout, unit)
        return this
    }

    /**
     * 写入超时时间
     * @param timeout 超时时间
     * @param unit 单位
     */
    fun setWriteTimeout(timeout: Long, unit: TimeUnit = TimeUnit.SECONDS): HummerConfig {
        mOkHttpBuilder.writeTimeout(timeout, unit)
        return this
    }

    /**
     * 设置重试次数
     * @param tryCount 重试次数
     * @param retryInterval 重试间隔 单位毫秒
     */
    fun setRetryTime(
        tryCount: Int = NetWorkConstant.RETRY_COUNT,
        retryInterval: Long = NetWorkConstant.RETRY_INTERVAL,
    ): HummerConfig {
        val retryInterceptor = RetryInterceptor.Builder().executionCount(tryCount) //重试次数
            .retryInterval(retryInterval) //重试间隔
            .build()
        addInterceptor(retryInterceptor)
        return this
    }

    /**
     * 设置HTTP_URL
     */
    fun setBaseUrl(baseUrl: String): HummerConfig {
        this.baseUrl = baseUrl
        return this
    }

    /**
     * 动态设置accessToken
     */
    fun addHeaders(block: () -> Map<String, String?>): HummerConfig {
        mHeaderInterceptor.headerBlock = block
        return this
    }
}